﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Linq;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Media;
using KgUtils.Collections;

namespace KgUtils.Wpf
{
    public static class WpfHelper
    {
        /// <summary>
        /// Validates the specified element and all its child controls.
        /// </summary>
        /// <param name="obj"></param>
        /// <returns></returns>
        public static bool FormIsValid(DependencyObject obj)
        {
            // The dependency object is valid if it has no errors, 
            //and all of its children (that are dependency objects) are error-free.
            return !System.Windows.Controls.Validation.GetHasError(obj) &&
                GetVisualTreeChildren(obj)
                .OfType<DependencyObject>()
                .All(child => FormIsValid(child));
        }

        /// <summary>
        /// Permet de récupérer la liste des enfants d'un objet visuel.
        /// VisualTreeHelper n'a pas de méthode retournant la liste de des enfants d'un objet visuel, juste le nombre et un accès par index.
        /// </summary>
        /// <param name="parent"></param>
        /// <returns></returns>
        private static IEnumerable GetVisualTreeChildren(DependencyObject parent)
        {
            for (int i = 0; i < VisualTreeHelper.GetChildrenCount(parent); i++)
                yield return VisualTreeHelper.GetChild(parent, i);
        }

        public static List<ValidationError> FormGetErrorMessages(DependencyObject obj)
        {
            var messages = new List<ValidationError>();
            FormGetErrorMessages(obj, messages);
            return messages;
        }

        private static void FormGetErrorMessages(DependencyObject obj, List<ValidationError> messages)
        {
            Guard.AssertNotNull(messages, "message");

            messages.AddRange(System.Windows.Controls.Validation.GetErrors(obj));
            LogicalTreeHelper.GetChildren(obj).OfType<DependencyObject>().ForEach(child => FormGetErrorMessages(child, messages));
        }
    }
}
